package cn.shop.dys.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.SystemClock;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import java.util.ArrayList;
import java.util.List;

import cn.shop.lib_common.CommonUtil;

/**
 * 转动view
 * Created by sunjian on 2016/4/15.
 */
public class RollMenuView extends View {
    private float mCommonRadius = 36;
    public static final int MENU_COUNT = 5;
    private Paint mCenterPaint;
    private Paint mLeftPaint;
    private Paint mTopPaint;
    private Paint mRightPaint;
    private Paint mBottomPaint;
    private PointF mCenterPoint = new PointF();
    private PointF mLeftPoint = new PointF();
    private PointF mTopPoint = new PointF();
    private PointF mRightPoint = new PointF();
    private PointF mBottomPoint = new PointF();
    private List<PointF> pointFs = new ArrayList<>();
    private List<Rect> rects = new ArrayList<>();
    private List<String> texts = new ArrayList<>();
    private List<Paint> paints = new ArrayList<>();
    private boolean isCircleAnimFinish;
    private float percent;
    private boolean isClick;
    private Paint mTextPaint;
    /*private Rect str1Rect;
    private Rect str2Rect;
    private Rect str3Rect;
    private Rect str4Rect;
    private Rect str5Rect;*/
    private boolean mIsLongPressed;
    private float downX;
    private float downY;
    private long mLastDownTime;
    private List<Rect> mapRects;
    private float centerX;
    private float centerY;
    private GestureDetector mGestureDetector;
    private boolean isFinish = false;
    private float mRollDegree = (float) (Math.PI * 1.0f);
    private Index finishIndex = Index.First;
    private OnRollClickListener mOnRollClickListener;
    private boolean mIsFinishPressed = true;

    private enum Index {
        First, Second, Third, Fourth, Finish
    }

    //(float) (Math.PI*0.25)
    public RollMenuView(Context context) {
        this(context, null);
    }

    public RollMenuView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RollMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setInitLoaction(float x, float y) {
        mCenterPoint.set(x, y);
        mLeftPoint.set(x - 3 * mCommonRadius, y);
        mRightPoint.set(x + 3 * mCommonRadius, y);
        mTopPoint.set(x, y - 3 * mCommonRadius);
        mBottomPoint.set(x, y + 3 * mCommonRadius);
        init();
    }

    private void init() {
        mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCenterPaint.setColor(Color.RED);
        mLeftPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLeftPaint.setColor(Color.GREEN);
        mTopPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTopPaint.setColor(Color.BLACK);
        mRightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mRightPaint.setColor(Color.BLUE);
        mBottomPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBottomPaint.setColor(Color.GRAY);
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(24);
        mTextPaint.setColor(Color.WHITE);
        paints.add(mLeftPaint);
        paints.add(mTopPaint);
        paints.add(mRightPaint);
        paints.add(mBottomPaint);
        paints.add(mCenterPaint);
        String str1 = "待付款";
        String str2 = "待发货";
        String str3 = "待收货";
        String str4 = "待评价";
        String str5 = "售后";
        texts.add(str1);
        texts.add(str2);
        texts.add(str3);
        texts.add(str4);
        texts.add(str5);
        pointFs.add(mLeftPoint);
        pointFs.add(mTopPoint);
        pointFs.add(mRightPoint);
        pointFs.add(mBottomPoint);
        pointFs.add(mCenterPoint);
        centerX = mCenterPoint.x;
        centerY = mCenterPoint.y;
        mGestureDetector = new GestureDetector(getContext(), callback);
        //  initText();
    }

    public void startAnim() {
        ValueAnimator valueAnimator = ObjectAnimator.ofFloat(1.0f);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedFraction = animation.getAnimatedFraction();
                //   Log.d("test", "animatedFraction" + animatedFraction);
                updateCenterCircle(animatedFraction);
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                percent = 0;
                isCircleAnimFinish = true;
                startRectAnim();
            }
        });
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(500);
        valueAnimator.start();
    }

    /**
     * 开始矩阵动画
     * 作者:孙建
     * created at 2016/4/25 14:45
     */
    private void startRectAnim() {
        ValueAnimator valueAnimator = ObjectAnimator.ofFloat(1.0f);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedFraction = animation.getAnimatedFraction();
                updateRect(animatedFraction);
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                isClick = true;
                initText();
            }
        });
        valueAnimator.setDuration(500);
        valueAnimator.start();
    }

    private void initText() {
        for (int i = 0; i < texts.size(); i++) {
            Rect rect = new Rect();
            paints.get(i).getTextBounds(texts.get(i), 0, texts.get(i).length(), rect);
            rects.add(rect);
        }
        /*str1Rect = new Rect();
        mTextPaint.getTextBounds(str1, 0, str1.length(), str1Rect);
        str2Rect = new Rect();
        mTextPaint.getTextBounds(str2, 0, str2.length(), str2Rect);
        str3Rect = new Rect();
        mTextPaint.getTextBounds(str3, 0, str3.length(), str3Rect);
        str4Rect = new Rect();
        mTextPaint.getTextBounds(str4, 0, str4.length(), str4Rect);
        str5Rect = new Rect();
        mTextPaint.getTextBounds(str5, 0, str5.length(), str5Rect);
        rects.add(str1Rect);
        rects.add(str2Rect);
        rects.add(str3Rect);
        rects.add(str4Rect);
        rects.add(str5Rect);*/

    }

    private void updateRect(float animatedFraction) {
        percent = animatedFraction;
        pointFs.get(0).set(CommonUtil.evaluateFloat(animatedFraction, pointFs.get(4).x, pointFs.get(4).x - mCommonRadius * 3.0f),
                pointFs.get(4).y);
        pointFs.get(1).set(pointFs.get(4).x,
                CommonUtil.evaluateFloat(animatedFraction, pointFs.get(4).y, pointFs.get(4).y - mCommonRadius * 3.0f));
        pointFs.get(2).set(CommonUtil.evaluateFloat(animatedFraction, pointFs.get(4).x, pointFs.get(4).x + mCommonRadius * 3.0f),
                pointFs.get(4).y);
        pointFs.get(3).set(pointFs.get(4).x,
                CommonUtil.evaluateFloat(animatedFraction, pointFs.get(4).y, pointFs.get(4).y + mCommonRadius * 3.0f));
        ViewCompat.postInvalidateOnAnimation(this);
    }

    private void updateCenterCircle(float animatedFraction) {
        percent = animatedFraction;
        ViewCompat.postInvalidateOnAnimation(this);
        //     Log.d("test", "changeRadiusout" + percent);
    }

    /**
     * 画图形逻辑
     * 作者:孙建
     * created at 2016/4/22 13:39
     */
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.translate(0, -CommonUtil.getStatusBarHeight(this));
        if (!isFinish) {
            if (!isClick) {
                if (isCircleAnimFinish) {
                    float changeRadius = mCommonRadius * percent;
                    drawRect(canvas, changeRadius);
                } else {
                    float changeRadius = mCommonRadius * percent;
                    canvas.drawCircle(pointFs.get(4).x, pointFs.get(4).y, changeRadius, paints.get(4));
                    //      Log.d("test", "changeRadius" + changeRadius);
                }
            } else {
                drawTextAndView(canvas);
                initRect();
            }
        } else {
            finishAnim(canvas);
         //   drawStatusText(canvas);
            initRect();
        }
        canvas.save();
        canvas.restore();
    }

    private void drawStatusText(Canvas canvas) {
        drawSingleText(canvas, texts.size() - 1);
        switch (finishIndex) {
            case First:
                drawCenterText(canvas, 0);
                Log.d("test", texts.get(0));
                for (int i = 1; i < texts.size(); i++) {
                    drawSingleText(canvas, i);
                }
                break;
            case Second:
                for (int i = 0; i < 2; i++) {
                    drawCenterText(canvas, i);
                }
                for (int i = 2; i < texts.size(); i++) {
                    drawSingleText(canvas, i);
                }
                break;
            case Third:
                for (int i = 0; i < 3; i++) {
                    drawCenterText(canvas, i);
                }
                for (int i = 3; i < texts.size(); i++) {
                    drawSingleText(canvas, i);
                }
                break;
            case Fourth:
                for (int i = 0; i < 4; i++) {
                    drawCenterText(canvas, i);
                }
                break;
            case Finish:
                for (int i = 0; i < 4; i++) {
                    drawCenterText(canvas, i);
                }
                break;
        }
    }

    private void drawCenterText(Canvas canvas, int i) {
        canvas.drawText(texts.get(i), centerX - rects.get(i).width() * 1.0f,
                centerY + rects.get(i).height() * 1.0f, mTextPaint);
    }

    private void drawSingleText(Canvas canvas, int i) {
        canvas.drawText(texts.get(i), pointFs.get(i).x - rects.get(i).width() * 1.0f,
                pointFs.get(i).y + rects.get(i).height() * 1.0f, mTextPaint);
    }

    private void finishAnim(Canvas canvas) {
        finishCenterAnim(canvas);
        switch (finishIndex) {
            case First:
                Log.d("test", "finishFirstAnim" + mRollDegree);
                finishFirstAnim(canvas);
                break;
            case Second:
                Log.d("test", "finishTwoAnim" + mRollDegree);
                finishTwoAnim(canvas);
                break;
            case Third:
                Log.d("test", "finishThreeAnim" + mRollDegree);
                finishThreeAnim(canvas);
                break;
            case Fourth:
                Log.d("test", "finishFourAnim" + mRollDegree);
                finishFourAnim(canvas);
                break;
            case Finish:
                Log.d("test", "finishFourAnim" + mRollDegree);
                finishAllAnim(canvas);
                break;
        }
    }

    private void finishAllAnim(Canvas canvas) {
        canvas.drawRect(centerX - mCommonRadius, centerY - mCommonRadius,
                centerX + mCommonRadius, centerY + mCommonRadius, paints.get(0));
        for (int i = 0; i < pointFs.size() - 1; i++) {
            //  if (pointFs.get(i).x == centerX&& pointFs.get(i).y == centerY+3.0f*mCommonRadius) continue;
            canvas.drawRect(centerX - mCommonRadius, centerY - mCommonRadius,
                    centerX + mCommonRadius, centerY + mCommonRadius, paints.get(i));
        }
    }

    private void finishCenterAnim(Canvas canvas) {
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) {
                canvas.drawCircle(pointFs.get(i).x, pointFs.get(i).y, mCommonRadius, paints.get(i));
                break;
            }
        }
    }

    private void finishFourAnim(Canvas canvas) {
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY + 3.0f * mCommonRadius) {
                if (mRollDegree >= Math.PI * 0.5f) {
                    canvas.drawRect(centerX - mCommonRadius, (float) (centerY + 1.5f * mCommonRadius + 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerX + mCommonRadius, (float) (centerY + 1.5f * mCommonRadius + 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            paints.get(i));
                } else {
                    canvas.drawRect(centerX - mCommonRadius, (float) (centerY + 1.5f * mCommonRadius + 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerX + mCommonRadius, (float) (centerY + 1.5f * mCommonRadius + 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            paints.get(i));
                }
                /*pointFs.get(i).set(centerX,(float) (centerY + 1.5f * mCommonRadius +
                        1.5f * mCommonRadius * Math.cos(mRollDegree)));*/
            } else {
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) continue;
                /*if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY+3.0f*mCommonRadius){
                    canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                            pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));
                    continue;
                }*/
                canvas.drawRect(centerX - mCommonRadius, centerY - mCommonRadius,
                        centerX + mCommonRadius, centerY + mCommonRadius, paints.get(i));
            }
        }
    }

    private void finishThreeAnim(Canvas canvas) {
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX + 3.0f * mCommonRadius && pointFs.get(i).y == centerY) {
                /*canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                        pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));*/
                if (mRollDegree >= Math.PI * 0.5f) {
                    canvas.drawRect((float) (centerX + 1.5f * mCommonRadius + 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY - mCommonRadius, (float) (centerX + 1.5f * mCommonRadius + 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY + mCommonRadius, paints.get(i));
                } else {
                    canvas.drawRect((float) (centerX + 1.5f * mCommonRadius + 0.5f * mCommonRadius * Math.cos(mRollDegree)), centerY - mCommonRadius,
                            (float) (centerX + 1.5f * mCommonRadius + 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY + mCommonRadius, paints.get(i));
                }
                /*pointFs.get(i).set((float) (centerX + 1.5f * mCommonRadius +
                        1.5f * mCommonRadius * Math.cos(mRollDegree)), centerY);*/
            } else {
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) continue;
                /*if (pointFs.get(i).x == centerX-3.0f*mCommonRadius && pointFs.get(i).y == centerY){
                    canvas.drawRect(centerX-mCommonRadius, centerY-mCommonRadius,
                            centerX+mCommonRadius, centerY+mCommonRadius,paints.get(i));
                    continue;
                }
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY-3.0f*mCommonRadius){
                    canvas.drawRect(centerX-mCommonRadius, centerY-mCommonRadius,
                            centerX+mCommonRadius, centerY+mCommonRadius,paints.get(i));
                    continue;
                }*/
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY + 3.0f * mCommonRadius) {
                    canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                            pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));
                    continue;
                }
                canvas.drawRect(centerX - mCommonRadius, centerY - mCommonRadius,
                        centerX + mCommonRadius, centerY + mCommonRadius, paints.get(i));
            }
        }
    }

    private void finishTwoAnim(Canvas canvas) {
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY - 3.0f * mCommonRadius) {
                /*canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                        pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));*/
                if (mRollDegree >= Math.PI * 0.5f) {
                    canvas.drawRect(centerX - mCommonRadius, (float) (centerY - 1.5f * mCommonRadius - 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerX + mCommonRadius, (float) (centerY - 1.5f * mCommonRadius - 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            paints.get(i));
                } else {
                    canvas.drawRect(centerX - mCommonRadius, (float) (centerY - 1.5f * mCommonRadius - 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerX + mCommonRadius, (float) (centerY - 1.5f * mCommonRadius - 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            paints.get(i));
                }
               /* pointFs.get(i).set(centerX,(float) (centerY - 1.5f * mCommonRadius -
                        1.5f * mCommonRadius * Math.cos(mRollDegree)));*/
            } else {
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) continue;
                if (pointFs.get(i).x == centerX - 3.0f * mCommonRadius && pointFs.get(i).y == centerY) {
                    canvas.drawRect(centerX - mCommonRadius, centerY - mCommonRadius,
                            centerX + mCommonRadius, centerY + mCommonRadius, paints.get(i));
                    continue;
                }
                canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                        pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));
            }
        }
    }

    private void finishFirstAnim(Canvas canvas) {
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX - 3.0f * mCommonRadius && pointFs.get(i).y == centerY) {
                /*canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                        pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));*/
                if (mRollDegree >= Math.PI * 0.5f) {
                    canvas.drawRect((float) (centerX - 1.5f * mCommonRadius - 0.5f * mCommonRadius * Math.cos(mRollDegree)), centerY - mCommonRadius,
                            (float) (centerX - 1.5f * mCommonRadius - 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY + mCommonRadius, paints.get(i));
                } else {
                    canvas.drawRect((float) (centerX - 1.5f * mCommonRadius - 2.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY - mCommonRadius, (float) (centerX - 1.5f * mCommonRadius - 0.5f * mCommonRadius * Math.cos(mRollDegree)),
                            centerY + mCommonRadius, paints.get(i));
                }
                /*pointFs.get(i).set((float) (centerX - 1.5f * mCommonRadius -
                        1.5f * mCommonRadius * Math.cos(mRollDegree)), centerY);*/
            } else {
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) continue;
                canvas.drawRect(pointFs.get(i).x - mCommonRadius, pointFs.get(i).y - mCommonRadius,
                        pointFs.get(i).x + mCommonRadius, pointFs.get(i).y + mCommonRadius, paints.get(i));
            }
        }
    }

    private void initRect() {
        mapRects = new ArrayList<>();
        for (int i = 0; i < rects.size(); i++) {
            Rect rect = new Rect((int) (pointFs.get(i).x - mCommonRadius), (int) (pointFs.get(i).y - mCommonRadius),
                    (int) (pointFs.get(i).x + mCommonRadius), (int) (pointFs.get(i).y + mCommonRadius));
            mapRects.add(rect);
        }
       /* if(isFirst){
            sMapRects.clear();
            sMapRects.addAll(mapRects);
        }*/
    }

    private void drawTextAndView(Canvas canvas) {
        drawRect(canvas, mCommonRadius);
        drawText(canvas);
       /* canvas.drawText(str1, pointFs.get(0).x - rects.get(0).width() * 0.5f,
                pointFs.get(0).y + rects.get(0).height() * 0.5f, mTextPaint);
        canvas.drawText(str2, pointFs.get(1).x - rects.get(1).width() * 0.5f,
                pointFs.get(1).y + rects.get(1).height() * 0.5f, mTextPaint);
        canvas.drawText(str3, pointFs.get(2).x - rects.get(2).width() * 0.5f,
                pointFs.get(2).y + rects.get(2).height() * 0.5f, mTextPaint);
        canvas.drawText(str4, pointFs.get(3).x - rects.get(3).width() * 0.5f,
                pointFs.get(3).y + rects.get(3).height() * 0.5f, mTextPaint);
        canvas.drawText(str5, pointFs.get(4).x - rects.get(4).width() * 0.5f,
                pointFs.get(4).y + rects.get(4).height() * 0.5f, mTextPaint);*/
    }

    private void drawText(Canvas canvas) {
        for (int i = 0; i < texts.size(); i++) {
            canvas.drawText(texts.get(i), pointFs.get(i).x - rects.get(i).width() * 1.0f,
                    pointFs.get(i).y + rects.get(i).height() * 1.0f, mTextPaint);
        }
    }

    private void drawRect(Canvas canvas, float changeRadius) {
       /* if(isFirst){
            for (int i = 0; i < pointFs.size(); i++) {

            }
        }else {

        }*/
        if (mIndex < 4 && mIndex >= 0) {
            for (int i = 0; i < pointFs.size(); i++) {
                if (i == mIndex) continue;
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) {
                    //     Log.d("test","结束了"+i);
                    canvas.drawCircle(pointFs.get(i).x, pointFs.get(i).y, mCommonRadius, paints.get(i));
                } else {
                    canvas.drawRect(pointFs.get(i).x - changeRadius, pointFs.get(i).y - changeRadius,
                            pointFs.get(i).x + changeRadius, pointFs.get(i).y + changeRadius, paints.get(i));
                }
                    /*canvas.drawRect(pointFs.get(i).x - changeRadius, pointFs.get(i).y - changeRadius,
                            pointFs.get(i).x + changeRadius, pointFs.get(i).y + changeRadius, paints.get(i));*/
            }
            //   canvas.drawCircle(pointFs.get(4).x, pointFs.get(4).y, mCommonRadius, paints.get(4));
            canvas.drawRect(pointFs.get(mIndex).x - changeRadius, pointFs.get(mIndex).y - changeRadius,
                    pointFs.get(mIndex).x + changeRadius, pointFs.get(mIndex).y + changeRadius, paints.get(mIndex));
        } else {
            for (int i = 0; i < pointFs.size(); i++) {
                if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) {
                    //  Log.d("test","结束了"+i);
                    canvas.drawCircle(pointFs.get(i).x, pointFs.get(i).y, mCommonRadius, paints.get(i));
                } else {
                    canvas.drawRect(pointFs.get(i).x - changeRadius, pointFs.get(i).y - changeRadius,
                            pointFs.get(i).x + changeRadius, pointFs.get(i).y + changeRadius, paints.get(i));
                }
               /* canvas.drawRect(pointFs.get(i).x - changeRadius, pointFs.get(i).y - changeRadius,
                        pointFs.get(i).x + changeRadius, pointFs.get(i).y + changeRadius, paints.get(i));*/
            }
            //   canvas.drawCircle(pointFs.get(4).x, pointFs.get(4).y, mCommonRadius, paints.get(4));
        }
       /* canvas.drawRect(mLeftPoint.x - changeRadius, mLeftPoint.y - changeRadius,
                mLeftPoint.x + changeRadius, mLeftPoint.y + changeRadius, mLeftPaint);
        canvas.drawRect(mTopPoint.x - changeRadius, mTopPoint.y - changeRadius,
                mTopPoint.x + changeRadius, mTopPoint.y + changeRadius, mTopPaint);
        canvas.drawRect(mRightPoint.x - changeRadius, mRightPoint.y - changeRadius,
                mRightPoint.x + changeRadius, mRightPoint.y + changeRadius, mRightPaint);
        canvas.drawRect(pointFs.get(3).x - changeRadius, pointFs.get(3).y - changeRadius,
                pointFs.get(3).x + changeRadius, pointFs.get(3).y + changeRadius, mBottomPaint);*/
    }

    private boolean isLongPressed(float lastX, float lastY, float thisX, float thisY, long lastDownTime,
                                  long thisEventTime, long longPressTime) {
        float offsetX = Math.abs(thisX - lastX);
        float offsetY = Math.abs(thisY - lastY);
        long intervalTime = thisEventTime - lastDownTime;
        if (offsetX <= 5 && offsetY <= 5 && intervalTime >= longPressTime) {
            return true;
        }
        return false;
    }

    private boolean isPressed(float lastX, float lastY, float thisX, float thisY, long lastDownTime,
                              long thisEventTime, long pressTime) {
        float offsetX = Math.abs(thisX - lastX);
        float offsetY = Math.abs(thisY - lastY);
        long intervalTime = thisEventTime - lastDownTime;
        if (offsetX <= 5 && offsetY <= 5 && intervalTime < pressTime) {
            return true;
        }
        return false;
    }

    private double firstDegree;

    public void setDegress(double newDegree) {
        firstDegree = newDegree;
        int j = 0;
        Log.d("test", "firstDegree" + firstDegree);
        for (int i = 0; i < pointFs.size(); i++) {
            if (pointFs.get(i).x == centerX && pointFs.get(i).y == centerY) {
                continue;
            }
            float x = (float) (centerX - Math.cos(firstDegree - j * Math.PI * 0.5f) * 3.0f * mCommonRadius);
            float y = (float) (centerY + Math.sin(firstDegree - j * Math.PI * 0.5f) * 3.0f * mCommonRadius);
            Log.d("test", x + "      x");
            pointFs.get(i).set(x, y);
            j++;
               /* if(pointFs.get(i).x==centerX&&pointFs.get(i).y==centerY){
                    pointFs.get(i).set(centerX,centerY);
                }else {

                }*/
        }
        ViewCompat.postInvalidateOnAnimation(this);
    }

    private ValueAnimator valueAnimator;
    private GestureDetector.OnGestureListener callback = new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            if (!mIsLongPressed) {
                double newDegree = Math.atan2(-e2.getRawY() + centerY, e2.getRawX() - centerX);
                double oldDegree = Math.atan2(-e2.getRawY() - distanceY + centerY, e2.getRawX() + distanceX - centerX);
                double currentDegree = newDegree - oldDegree;
                //    Log.d("test","currentDegree"+currentDegree);
                setDegress(firstDegree + currentDegree);
            }
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

        private void rollAnimator(double unitDegree) {
            //  Log.d("test","unitDegree"+unitDegree);
            long duration = (long) (Math.abs(unitDegree / Math.PI / 2) * 1000);//随便 时间比例*一个常量值
            double totalDegree = unitDegree * duration / 4000;
            //  Log.d("test","totalDegree"+totalDegree);
            valueAnimator = ValueAnimator.ofFloat((float) firstDegree, (float) (firstDegree + totalDegree));
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    Float value = (Float) animation.getAnimatedValue();
                    //   Log.d("test",value+"value");
                    setDegress(value);
                }
            });
            valueAnimator.setInterpolator(new DecelerateInterpolator(2));
            valueAnimator.setDuration(duration);
            valueAnimator.start();
        }
        /* @Override
         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
             double oldDegree=Math.atan2(-e2.getRawY() + centerY, e2.getRawX() - centerX);
             double newDegree=Math.atan2(-e2.getRawY() - velocityY / 1000+ centerY,
                     e2.getRawX() + velocityX / 1000 - centerX);
             double unitDegree = (newDegree - oldDegree) * 1000;
             rollAnimator(unitDegree);
             return true;
         }

         @Override
         public boolean onSingleTapUp(MotionEvent e) {
             return super.onSingleTapUp(e);
         }

         @Override
         public void onLongPress(MotionEvent e) {
             super.onLongPress(e);
             float moveX = e.getRawX();
             float moveY = e.getRawY();
             int index = getPointIndex((int) moveX, (int) moveY);
             if (index >= 0) {
                 //      Log.d("test","长按了");
                 if(isFirst){
                     isFirst=false;
                     prePoint.set(pointFs.get(index).x,pointFs.get(index).y);
                     updateDragPoint(moveX, moveY, index);
                 }else {
                     updateDragPoint(moveX, moveY);
                 }
             }
         }

         @Override
         public boolean onDown(MotionEvent e) {
             if (valueAnimator != null && valueAnimator.isRunning()) {
                 valueAnimator.cancel();
             }
             return true;
         }*/

    };

    private boolean isScroll(float lastX, float lastY, float thisX, float thisY, long lastDownTime,
                             long thisEventTime, long pressTime) {
        float offsetX = Math.abs(thisX - lastX);
        float offsetY = Math.abs(thisY - lastY);
        long intervalTime = thisEventTime - lastDownTime;
        if (offsetX > 5 && offsetY > 5 && intervalTime > pressTime) {
            return true;
        }
        return false;
    }

    private boolean mIsScroll;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isClick) return false;
       /* if(getPointIndex((int)event.getRawX(),(int)event.getRawY())>=0){
            mGestureDetector.onTouchEvent(event);
            //  Log.d("test","b"+b);
        }*/
        // Log.d("test","进来了");
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getRawX();
                downY = event.getRawY();
                mLastDownTime = SystemClock.uptimeMillis();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = event.getRawX();
                float moveY = event.getRawY();
                if (!mIsLongPressed && !mIsScroll) {
                    long currentDownTime = SystemClock.uptimeMillis();
                    mIsLongPressed = isLongPressed(downX, downY, moveX, moveY, mLastDownTime, currentDownTime, 600);
                    if (!mIsLongPressed) {
                        mIsScroll = isScroll(downX, downY, moveX, moveY, mLastDownTime, currentDownTime, 200);
                    }
                }
                if (mIsLongPressed) {
                    int index = getPointIndex((int) moveX, (int) moveY);
                    if (index >= 0) {
                        //      Log.d("test","长按了");
                        if (isFirst) {
                            isFirst = false;
                            prePoint.set(pointFs.get(index).x, pointFs.get(index).y);
                            updateDragPoint(moveX, moveY, index);
                        } else {
                            updateDragPoint(moveX, moveY);
                        }
                    }
                    /*if(!mIsScroll){

                    }else {
                        mIsLongPressed=false;
                    }*/
                } else {
                    if (mIsScroll) {
                        Log.d("test", "进来了");
                        double newDegree = Math.atan2(-moveY + centerY, moveX - centerX);
                        float distanceX = downX - moveX;
                        float distanceY = downY - moveY;
                        double oldDegree = Math.atan2(-moveY - distanceY + centerY, moveX + distanceX - centerX);
                        double currentDegree = newDegree - oldDegree;
                        //    Log.d("test","currentDegree"+currentDegree);
                        setDegress(firstDegree + currentDegree);
                        downY = moveY;
                        downX = moveX;
                    }
                }

                break;
            case MotionEvent.ACTION_UP:
                float upX = event.getRawX();
                float upY = event.getRawY();
                long currentDownTime = SystemClock.uptimeMillis();
                if (mIsLongPressed) {
                    if (mIndex >= 0) {
                        pointFs.get(mIndex).set(prePoint.x, prePoint.y);
                        isFirst = true;
                        mIndex = -1;
                        mIsLongPressed = false;
                        ViewCompat.postInvalidateOnAnimation(this);
                        prePoint = new PointF();
                    }

                }
                if (mIsScroll) {
                    mIsScroll = false;
                    double rangeDegree = firstDegree % (2 * Math.PI);
                    if (rangeDegree < 0) {
                        rangeDegree += 2 * Math.PI;
                    }
                    if (rangeDegree >= Math.PI * 1.75 && rangeDegree < 2 * Math.PI) {
                        setDegress(firstDegree + 2 * Math.PI - rangeDegree);
                    } else if (rangeDegree >= Math.PI * 1.5 && rangeDegree < Math.PI * 1.75) {
                        setDegress(firstDegree - (rangeDegree - 1.5 * Math.PI));
                    } else if (rangeDegree >= Math.PI * 1.25 && rangeDegree < Math.PI * 1.5) {
                        setDegress(firstDegree + 1.5 * Math.PI - rangeDegree);
                    } else if (rangeDegree >= Math.PI * 1.0 && rangeDegree < Math.PI * 1.25) {
                        setDegress(firstDegree - (rangeDegree - 1.0 * Math.PI));
                    } else if (rangeDegree >= Math.PI * 0.75 && rangeDegree < Math.PI * 1.0) {
                        setDegress(firstDegree + 1.0 * Math.PI - rangeDegree);
                    } else if (rangeDegree >= Math.PI * 0.5 && rangeDegree < Math.PI * 0.75) {
                        setDegress(firstDegree - (rangeDegree - 0.5 * Math.PI));
                    } else if (rangeDegree >= Math.PI * 0.25 && rangeDegree < Math.PI * 0.5) {
                        setDegress(firstDegree + 0.5 * Math.PI - rangeDegree);
                    } else if (rangeDegree >= 0 && rangeDegree < Math.PI * 0.25) {
                        setDegress(firstDegree - (rangeDegree - 0 * Math.PI));
                    }

                }
                if (isPressed(downX, downY, upX, upY, mLastDownTime, currentDownTime, 500)) {
                    int index = getPointIndex((int) upX, (int) upY);
                    if (index >= 0) {
                        if (mOnRollClickListener != null) {
                            mOnRollClickListener.onRollClick(index);
                        }
                    } else {
                        if (!(upX > centerX - 8 * mCommonRadius && upX < centerX + 8 * mCommonRadius && upY > centerY - 8 * mCommonRadius && upY < centerY + 8 * mCommonRadius)) {
                            if (mIsFinishPressed) {
                                mIsFinishPressed = false;
                                setClickable(false);
                                isFinish = true;
                                Log.d("test", "点外面了");
                                startFinishAnim();
                            }
                        }
                    }
                }
                break;
        }
        return true;
    }

    public void setOnRollClickListener(OnRollClickListener mOnRollClickListener) {
        this.mOnRollClickListener = mOnRollClickListener;
    }

    public interface OnRollClickListener {
        void onRollClick(int index);
    }

    private void startFinishAnim() {
        ValueAnimator valueAnimator = ObjectAnimator.ofFloat(1.0f);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mRollDegree = (float) (animation.getAnimatedFraction() * Math.PI);
                /*if(finishIndex==null){
                    Log.d("test","First");
                    finishIndex=Index.First;
                }else if(finishIndex==Index.First){
                    Log.d("test","Second");
                    finishIndex=Index.Second;
                }else if(finishIndex==Index.Second){
                    Log.d("test","Third");
                    finishIndex=Index.Third;
                }else if(finishIndex==Index.Third){
                    Log.d("test","Fourth");
                    finishIndex=Index.Fourth;
                }*/
                ViewCompat.postInvalidateOnAnimation(RollMenuView.this);
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mRollDegree = 0;
                if (finishIndex == Index.First) {
                    finishIndex = Index.Second;
                    startFinishAnim();
                    return;
                }
                if (finishIndex == Index.Second) {
                    finishIndex = Index.Third;
                    startFinishAnim();
                    return;
                }
                if (finishIndex == Index.Third) {
                    finishIndex = Index.Fourth;
                    startFinishAnim();
                    return;
                }
                if (finishIndex == Index.Fourth) {
                    finishIndex = Index.Finish;
                    startFinishAnim();
                    return;
                }
                if (finishIndex == Index.Finish) {
                    if (listener != null) {
                        listener.finish();
                    }
                    return;
                }
            }
        });
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(500);
        valueAnimator.start();
    }

    private OnRollMenuViewListener listener;

    public void setOnRollMenuViewListener(OnRollMenuViewListener listener) {
        this.listener = listener;
    }

    public interface OnRollMenuViewListener {
        void finish();
    }

    private void updateDragPoint(float moveX, float moveY) {
        updateDragPoint(moveX, moveY, mIndex);
    }

    private int getPointIndex(int x, int y) {
        for (int i = 0; i < mapRects.size(); i++) {
            //  Log.d("test",mapRects.get(i).left+"");
            if (mapRects.get(i).contains(x, y)) {
                /*if(isFirst){
                    return i;
                }*/
                if (i == mIndex) {
                    for (int j = i + 1; j < mapRects.size(); j++) {
                        if (mapRects.get(j).contains(x, y)) {
                            return j;
                        }
                    }
                }
                return i;
                //  return i;
            }
        }
        return -1;
    }

    private int mIndex = -1;
    private boolean isFirst = true;
    private PointF prePoint = new PointF();
    private List<Rect> sMapRects = new ArrayList<>();

    private void updateDragPoint(float x, float y, int index) {
        this.mIndex = index;
        /*for (int i = 0; i < mapRects.size(); i++) {
            Log.d("test","进来了"+i+"  "+mapRects.get(i).left);
        }*/
        //   Log.d("test","index"+index);
        int coverIndex = getPointIndex((int) x, (int) y);
        //   Log.d("test","coverIndex"+coverIndex);
        if (coverIndex != index && coverIndex >= 0) {
            float currentX = pointFs.get(coverIndex).x;
            float currentY = pointFs.get(coverIndex).y;
            //   Log.d("test","currentX"+currentX);
            pointFs.get(coverIndex).set(prePoint.x, prePoint.y);
            prePoint.set(currentX, currentY);
        }
        pointFs.get(index).set(x, y);
        ViewCompat.postInvalidateOnAnimation(this);
    }
}
